package com.xxl.sso.server.controller;

import com.xxl.sso.core.constant.Const;
import com.xxl.sso.core.helper.XxlSsoHelper;
import com.xxl.sso.core.model.LoginInfo;
import com.xxl.sso.server.model.AccountInfo;
import com.xxl.sso.server.model.LoginRequest;
import com.xxl.sso.server.service.AccountService;
import com.xxl.tool.core.StringTool;
import com.xxl.tool.id.UUIDTool;
import com.xxl.tool.response.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.util.HashMap;
import java.util.Map;

/**
 * login page (for cas)
 * <p>
 * 2017-08-01 21:39:47
 */
@Controller
public class CasLoginController {

    @Autowired
    private AccountService accountService;

    @RequestMapping("/")
    public String index(Model model, HttpServletRequest request, HttpServletResponse response) {

        // login check
        Response<LoginInfo> loginCheckResult = XxlSsoHelper.loginCheckWithCookie(request, response);

        if (loginCheckResult != null && loginCheckResult.isSuccess()) {
            model.addAttribute("loginInfo", loginCheckResult.getData());
            return "index";
        } else {
            return "redirect:/login";
        }
    }

    /**
     * Login page
     *
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(Const.LOGIN_URL)
    public String login(Model model, HttpServletRequest request, HttpServletResponse response) {

        // 1、param
        String redirectUrl = request.getParameter(Const.CLIENT_REDIRECT_URL);

        // 2、login check
        Response<LoginInfo> loginCheckResult = XxlSsoHelper.loginCheckWithCookie(request, response);
        if (loginCheckResult != null && loginCheckResult.isSuccess()) {

            // 2.1、login success, redirect back
            String redirectUrlFinal = genereteRedirectUrl(request, redirectUrl);
            if (StringTool.isBlank(redirectUrlFinal)) {
                redirectUrlFinal = "/";
            }

            return "redirect:" + redirectUrlFinal;
        } else {

            // 2.2、login fail, go to login-page
            model.addAttribute(Const.CLIENT_REDIRECT_URL, redirectUrl);

            return "login";
        }
    }

    /**
     * generate redirect url, back 2 client
     *
     * @param request
     * @param redirectUrl
     * @return
     */
    private String genereteRedirectUrl(HttpServletRequest request, String redirectUrl) {

        // valid
        if (StringTool.isBlank(redirectUrl)) {
            return "";
        }

        // parse ticket
        Response<String> createTicketResult = XxlSsoHelper.createTicket(request);
        if (!createTicketResult.isSuccess()) {
            return "";
        }
        String ticket = createTicketResult.getData();

        // build redirect url
        return redirectUrl.trim() + "?" + Const.XXL_SSO_TICKET + "=" + ticket;
    }

    /**
     * Do login
     *
     * @param request
     * @param loginRequest
     * @return
     */
    @PostMapping("/doLogin")  // 改为@PostMapping明确指定为POST请求
    @ResponseBody
    public Response<Map<String, Object>> doLogin(HttpServletRequest request, HttpServletResponse response, @RequestBody LoginRequest loginRequest) {  // 修改返回类型为Map

        // process param - 从LoginRequest对象中获取各个参数
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();
        String ifRemember = loginRequest.getIfRemember();
        boolean ifRem = "on".equals(ifRemember);

        // 1、find user
        Response<AccountInfo> accountResult = accountService.findUser(username, password);
        if (!accountResult.isSuccess()) {
            return Response.ofFail(accountResult.getMsg());
        }
        AccountInfo accoutInfo = accountResult.getData();

        // 2、build LoginInfo
        LoginInfo loginInfo = new LoginInfo(accoutInfo.getUserid(), accoutInfo.getUsername(), null, null, accoutInfo.getRoleList(), accoutInfo.getPermissionList(), -1, UUIDTool.getSimpleUUID());

        try {
            // 3、生成JWT token
            Response<String> loginResult = XxlSsoHelper.loginWithCookie(loginInfo, response, ifRem);
            if (!loginResult.isSuccess()) {
                return Response.ofFail(accountResult.getMsg());
            }

            // 4、获取登录后的token
            String token = loginResult.getData();

            // 5、构建用户信息对象
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("userId", accoutInfo.getUserid());
            userInfo.put("username", accoutInfo.getUsername());
            userInfo.put("roleList", accoutInfo.getRoleList());
            userInfo.put("permissionList", accoutInfo.getPermissionList());
            // 6、构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("userInfo", userInfo);
            
            return Response.ofSuccess(result);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.ofFail("登录失败：" + e.getMessage());
        }
    }

    /**
     * Logout
     *
     * @param request
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(Const.LOGOUT_URL)
    public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {

        // logout
        XxlSsoHelper.logoutWithCookie(request, response);

        // redirect 2 login
        redirectAttributes.addAttribute(Const.CLIENT_REDIRECT_URL, request.getParameter(Const.CLIENT_REDIRECT_URL));
        return "redirect:/login";
    }

}